# https://www.bilibili.com/video/BV1y84y197Yq/?spm_id_from=333.1387.favlist.content.click&vd_source=b664701fe1351134c3243c7903d11516
import torch
import torch.nn as nn
x1 = torch.tensor(2.) #第一层的数据 N=1
x2 = torch.tensor(3.) #第一层的数据 N=2
Y = torch.tensor(5.) # 样本
# 初始化w w_11_2=1, w_21_2=0, w_12_2=1, w_22_2=0, w_13_2=0, w_23_2=0,  
# w_11_3=1, w_21_3=1, w_31_3=0
# w权重的命名按照谈芯说AI的来
w_11_2, w_12_2,                 w_11_3, w_21_3 = torch.tensor([1.,1.,1.,1.],requires_grad=True)
w_21_2, w_22_2, w_13_2, w_23_2, w_31_3 = torch.tensor([0.,0.,0.,0.,0.],requires_grad=True)
lr = 0.001
w_11_2.retain_grad()
w_21_2.retain_grad()
w_12_2.retain_grad()
w_22_2.retain_grad()
w_13_2.retain_grad()
w_23_2.retain_grad()
w_11_3.retain_grad()
w_21_3.retain_grad()
w_31_3.retain_grad()

print(f"x1:{x1} \n")
print(f"x2:{x2} \n")
print(f"Y:{Y} \n")

def relu(x):
    if x>0:
        return x
    else:
        return 0
# 前向传播
z1 = w_11_2 * x1 + w_21_2 * x2 # 第二层的第一个神经元
a1 = relu(z1)

z2 = w_12_2 * x1 + w_22_2 * x2
a2 = relu(z2)

z3 = w_13_2 * x1 + w_23_2 * x2
a3 = relu(z3)

y = relu(w_11_3 * a1 + w_21_3 * a2 + w_31_3 *a3)
loss = pow(y-Y,2)

#反向传播
loss.backward()

w_11_2.grad # 反向传播计算出的梯度
print(f"w_11_2.grad:{w_11_2.grad} \n")
w_11_2 = w_11_2-lr*w_11_2.grad
print(f"w_11_2:{w_11_2} \n")
w_21_2.grad # 反向传播计算出的梯度
w_12_2.grad # 反向传播计算出的梯度
w_22_2.grad # 反向传播计算出的梯度
w_13_2.grad # 反向传播计算出的梯度
w_23_2.grad # 反向传播计算出的梯度
w_11_3.grad # 反向传播计算出的梯度
w_21_3.grad # 反向传播计算出的梯度
w_31_3.grad # 反向传播计算出的梯度


